iOS开发数据库SQLite的使用
iOS系统自带Core Data来进行持久化处理,而且Core Data可以使用图形化界面来创建对象,但是Core Data不是关系型数据库,对于Core Data来说比较擅长管理在设备上创建的数据持久化存储用户创建的对象,但是要处理大量的数据时就应该优先选择SQL关系型数据库来存储这些数据。
Core Data在后台也是使用SQLite来存储数据的,但是开发人员不能直接访问这些数据,只能通过Core Data提供的API来操作,如果一旦人为的通过SQLite修改这些数据那么使用Core Data再次访问这些数据时就会发生错误。
SQLite是使用C语言写的开源库,实现了一个自包含的SQL关系型数据库引擎,可以使用SQLite存储操作大量的数据,作为关系型数据库我们可以在一个数据库中建立多张相关联的表来解决大量数据重复的问题。而且SQLite库也针对移动设备上的使用进行了优化。
因为SQLite的接口使用C写的,而且Objective-C是C的超集所以可以直接在项目中使用SQLite。
开始之前首先要想到需要存什么数据,然后怎么设计这个数据库。
首先我们设计一个数据库用来存储人员信息如下:
1 jhon 20 jhon@mail beijing
2 peter 20 peter@mail shanghai
3 july 20 july@mail beijing
4 elev 20 elev@mail shenzhen
5 ribet 20 ribet@mail beijing
上面是所有的人员信息,实际可能比这个多很多。但是我们发现region这一行中有很多的数据重复出现。很多人可能来自同一个地方,为了避免这种情况我们应该再重新创建一张表来单独存储region这列的信息然后在这个表中引用region表中的信息。当然我们还可以在region表中添加更多的信息比如详细地址。现在创建两张表people与region如下所示
people表 id name age email region1 jhon 20 jhon@mail 1
2 peter 20 peter@mail 2
3 july 20 july@mail 1
4 elev 20 elev@mail 3
5 ribet 20 ribet@mail 1
region表 regionid regioninfo address
1 beijing fengtai
2 shanghai jingan
3 shenzhen futian
使用SQLite创建数据库
为了熟悉SQLite语句,打开shell使用SQLite命令行来创建一个数据库
打开创建数据库打开shell切换到指定目录输入 sqlite3 database.db
这行命令是启动sqlite命令行并且创建新的数据库database.db并附加该数据到命令行
此时已经进入sqlite命令行通过输入.help可以显示可以使用哪些命令,通过输入.databases来查看当前有哪些数据库附加到当前的命令行工具中。输入.quit或.exit退出当前命令行工具
这条命令是创建一个people的表,并且将id字段设为primary key主键将其指定为一个autoincrement自动增长的字段。表示不用提供id的值数据库将自动生成。后面的表示该张表中所含有的字段。
因为要设计两张表所以还需要创建region表
create table 'main'.'region' ('regionid' integer primary key autoincrement not null, 'regioninfo' text,'address' text not null); 添加数据此时已经成功创建了两张表我们要添加数据进去 insert into 'main'.'people' ('name','age','email','region') values ('jhon','20','jhon@mail','1');
这样成功往people表成功的插入了一条数据。这样写效率比较低。每次只能插入一条数据不要担心SQLite支持将文件直接导入数据库中。可以是普通的文件文件也可以是excel文件。下面我们创建一个people.txt文件格式如下:
1 jhon 20 jhon@mail 1 2 peter 20 peter@mail 2 3 july 20 july@mail 1 4 elev 20 elev@mail 3 5 ribet 20 ribet@mail 1注意每个字段之间的空隙是用制表符 来分割的,也就是创建文件是每个字段用tab键进行分割。字段的顺序必须和表中的顺序相同然后将people.txt文件导入people表中
.separator ' '根据 来分割字段,然后接着输入
.import 'people.txt' people导入people.txt文件到people表中此时会提示如下错误信息
people.txt:1: INSERT failed: UNIQUE constraint failed: people.id不用担心这个意思是说已经存在了一个id为1的数据所以这条数据插入失败,是因为我们之前手动了插入了一条数据。可以通过以下指令来查插入的数据
select * from people;然后用同样的方法创建一个region.txt的文件并将其导入region表中。
注意
使用SQLite命令行可能会出现...>这表示指令输入错误,按ctrl+d即可退出
查询popple表中的所有数据
链接表数据
select name,regioninfo from people,region where people.region=region.regionid;输出结果
jhon beijing peter shanghai july beijing elev shenzhen ribet beijing从people和region表中查找name与regioninfo字段并且只查询people.region=region.regionid相匹配的结果,如果没有这个条件那么将出现5*3=15条数据
如果要查找某个地区的人使用where来筛选条件
select name,regioninfo from people,region where people.region=region.regionid and region.regioninfo='beijing';输出结果
jhon beijing july beijing ribet beijing iOS中SQLite的使用开始之前应该在项目中引用SQLite库。TARGETS->General->Linked Frameworks and Libraries如下图所示

将之前创建好的database.db文件导入项目中,并引入sqlite3.h头文件
#import <sqlite3.h>使用SQLite需要一下几个步骤
声明类变量sqlite3来保存对数据库的引用 使用sqlite3_open打开数据库 创建SQLite语句 创建SQLite语句对象sqlite3_stmt 准备SQLite语句sqlite3_prepare_v2 开始遍历结果sqlite3_step初始化打开数据库
sqlite3 * database; -(void)initDatabase { NSString *path = [[NSBundle mainBundle] pathForResource:@'database' ofType:@'db']; if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) { NSLog(@'open database'); } else{ sqlite3_close(database); NSLog(@'error %s',sqlite3_errmsg(database)); } }打开数据库如果返回的状态码不是SQLITE_OK那么打开失败关闭数据库并且输出错误信息
查询数据
-(void)operateDatabase { const char * sql = 'select name,regioninfo from people,region where people.region=region.regionid'; sqlite3_stmt *statement; //创建sql语句对象 int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL); //准备sql语句 if ( sqlResult== SQLITE_OK) //是否准备结束 { while (sqlite3_step(statement) == SQLITE_ROW) //开始遍历查询结果 { NSLog(@'name %s, region %s',sqlite3_column_text(statement, 0),sqlite3_column_text(statement, 1)); } } }输出结果:
name jhon, region beijing name peter, region shanghai name july, region beijing name elev, region shenzhen name ribet, region beijingsqlite3_prepare_v2的参数第一个是数据库连接,第二个是sql语句,第三个是这个语句的长度传入-1表示地道第一个null终止符为止,第四个是返回一个语句对象,第五个是返回一个指向该sql语句的第一个字节的指针。
当sqlite3_prepare_v2返回状态码SQLITE_OK时开始遍历结果。
sqlite3_step用来遍历结果如果返回为SQLITE_ROW表示下一行准备结束可以开始查询。所以此处用一个while来便利所以查询的结果
遍历的过程中要取到结果通过一下的函数获取遍历结果
上面是所支持的结果类型,第一个参数为sql语句对象,第二个为获取哪一列的信息。
参数化查询
上面的情况每次sql语句都写死了,如果想要改变某个条件就需要重新写一条语句,幸好sqlite支持参数化查询,每次只需要更改查询条件就可以而不用更改整条sql语句,如果现在只想查询北京地区的人口信息使用参数化查询如下:
-(void)operateDatabase { const char * sql = 'select name,regioninfo from people,region where people.region=region.regionid and regioninfo=http://www.it165.net/database/html/201607/?'; sqlite3_stmt *statement; //创建sql语句对象 int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL); //准备sql语句 sqlite3_bind_text(statement, 1, 'beijing', -1,SQLITE_TRANSIENT); //绑定参数 if ( sqlResult== SQLITE_OK) //是否准备结束 { while (sqlite3_step(statement) == SQLITE_ROW) //开始遍历查询结果 { NSLog(@'name %s, region %s',sqlite3_column_text(statement, 0),sqlite3_column_text(statement, 1)); } } }输出结果:
name jhon, regionbeijing name july, regionbeijing name ribet, regionbeijing可见需要更改的条件sql中用?来代替,然后用sqlite3_bind_text函数来绑定参数。根据类型不同绑定的函数也不同
SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,void(*)(void*)); SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double); SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int); SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int); SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,void(*)(void*), unsigned char encoding); SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);上面列出了所有支持绑定类型的函数。
结束本篇只是列出了SQLite常用的基础方法,实际开发中数据库可能要比这复杂许多,而且还要考虑数据竞争线程安全的问题。具体还是要自己在开发中实践。
相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://v30.fanwenzhu.com/sql/sqlite/10591.shtml
相关文章
热门TAG
win10 ecshop 主机 阿里云 解决 配置 C# C++ 解析 SQL语句 命令 Go语言 方法 CSS3 HTML5 CSS win7 MSSQL 服务器配置 IIS7.5 IIS7 IIS6 IIS CentOS 7 Linux oracle数据库 oracle phpcms discuz discuz教程最新文章
-
sqlite只通过文件锁就可以
时间:2021-01-23
-
返回的是一个SQLiteDatabas
时间:2021-01-23
-
只不过它是OC方式封装了
时间:2021-01-23
-
应该增加autoincrementcreate
时间:2021-01-23
-
如果没有就从Bundle中把数
时间:2021-01-23
-
Linux 部署ASP.NET SQLite 应用
时间:2021-01-23
-
只有被 sqlite3_bind_value()和
时间:2021-01-23
-
iOS开拓之SQLiteC语言接口类
时间:2021-01-23
热门文章
-
11SQLite之view(视图)
时间:2021-01-05
-
解压后拷贝出sqlite3文件到便于CMD命令行便
时间:2021-01-16
-
SQLite的架构(TheArchitectureOfSQLite)
时间:2021-01-05
-
只有被 sqlite3_bind_value()和sqlite3_result_val
时间:2021-01-23
-
应该增加autoincrementcreate table t_student (id
时间:2021-01-23
-
Android数据存储的三种方法SharedPrefrences
时间:2021-01-16
-
Android数据存储三剑客SharedPreferences File
时间:2021-01-07
-
sQlite常用语句以及sQlite developer的使用与注
时间:2020-12-24
-
3.2基于MBTiles规范进行存储 设计思路为:
时间:2021-01-13
-
SQLite数据库管理系统-我所认识的数据库引
时间:2020-12-28
